﻿using System;

namespace Transformable_Engine_v2.Engine.Animation.Trajectory
{
    public class BounceEasing : BaseTrajectory
    {
        private readonly Easing _easing;
        private double _bounceFactor;

        public BounceEasing(Easing easing, double bounceFactor = 7.5625)
        {
            _easing = easing;
            _bounceFactor = bounceFactor;
        }


        public override double GetPercentageProgression(double elapsedDurationTime)
        {
            switch (_easing)
            {
                case Easing.EaseIn:
                    return GetEaseIn(elapsedDurationTime);
                case Easing.EaseOut:
                    return GetEaseOut(elapsedDurationTime);
                case Easing.EaseInAndOut:
                    return GetEaseInAndOut(elapsedDurationTime);
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private double GetEaseOut(double elapsedDurationTime)
        {
            if (elapsedDurationTime < (1 / 2.75))
                return (_bounceFactor * Math.Pow(elapsedDurationTime, 2));

            if (elapsedDurationTime < (2 / 2.75))
                return (_bounceFactor * Math.Pow(elapsedDurationTime - (1.5 / 2.75), 2) + 0.75);

            if (elapsedDurationTime < (2.5 / 2.75))
                return (_bounceFactor * Math.Pow(elapsedDurationTime - (2.25 / 2.75), 2) + 0.9375);

            return (_bounceFactor * Math.Pow(elapsedDurationTime - (2.625 / 2.75), 2) + 0.984375);
        }

        private double GetEaseIn(double elapsedDurationTime)
        {
            return 1 - GetEaseOut(1 - elapsedDurationTime);
        }

        private double GetEaseInAndOut(double elapsedDurationTime)
        {
            if (elapsedDurationTime < 0.5)
                return 0.5 * GetEaseIn(2*elapsedDurationTime);

            return 0.5 + 0.5 * GetEaseOut((elapsedDurationTime - 0.5)*2);

        }
    }
} 